//
// Created by alexa on 5/23/2024.
//

#include <conio.h>
#include "MissilesMenu.h"
#include "../../keydown-handler/KeydownHandler.h"
#include "../../valid-input/ValidInput.h"

MissilesMenu::MissilesMenu(i18n::Translator *t, UserInterface *ui, MissilesService *service) : Menu(t, ui),
                                                                                               service(service) {

}

void MissilesMenu::displayMenu() {
    printMenu();

    return keydownHandle(ui->getPressedKey, {
            {Keys::TAB,   [this]() {
                ui->toggleLocale();
                return displayMenu();
            }},
            {Keys::ESC,   [this]() {
                ui->setCurrentPage(Pages::MAIN_MENU);
                return;
            }},
            {Keys::KEY_1, [this]() {
                return displayMissilesList();
            }},
            {Keys::KEY_2, [this]() {
                return findAndDisplayMissileInfo();
            }},
            {Keys::KEY_3, [this]() {
                return createMissile();
            }},
            {Keys::KEY_4, [this]() {
                Missile *missile = findMissile();
                return deleteMissile(missile);
            }}
    });
}

void MissilesMenu::printMenu() {
    clearScreen();
    printKeybinds();
    cout << (*t)("title", "missiles.main") << endl;
    cout << "1. " << (*t)("option1", "missiles.main") << endl;
    cout << "2. " << (*t)("option2", "missiles.main") << endl;
    cout << "3. " << (*t)("option3", "missiles.main") << endl;
    cout << "4. " << (*t)("option4", "missiles.main") << endl;
    cout << (*t)("select-action", "general",
                 {
                         {"min", "1"},
                         {"max", "4"}
                 });
}

void MissilesMenu::createMissile() {
    clearScreen();
    string name = vi::inputString((*t)("enter-name", "missiles.create"));
    int calibre = -1;
    while (calibre <= 0) {
        calibre = vi::inputInt((*t)("enter-calibre", "missiles.create", {{"unit", (*t)("mm", "measurement-units")}}));
    }
    float length = -1;
    while (length <= 0) {
        length = vi::inputFloat((*t)("enter-length", "missiles.create", {{"unit", (*t)("m", "measurement-units")}}));
    }
    float weight = -1;
    while (weight <= 0) {
        weight = vi::inputFloat((*t)("enter-weight", "missiles.create", {{"unit", (*t)("kg", "measurement-units")}}));
    }
    float flightRange = -1;
    while (flightRange <= 0) {
        flightRange = vi::inputFloat(
                (*t)("enter-flight-range", "missiles.create", {{"unit", (*t)("km", "measurement-units")}}));
    }
    float impactArea = -1;
    while (impactArea <= 0) {
        impactArea = vi::inputFloat(
                (*t)("enter-impact-area", "missiles.create", {{"unit", (*t)("m", "measurement-units")}}));
    }
    float speed = -1;
    while (speed <= 0) {
        speed = vi::inputFloat((*t)("enter-speed", "missiles.create", {{"unit", (*t)("m/s", "measurement-units")}}));
    }
    Missile *missile = service->createOne(name, calibre, length, weight, flightRange, impactArea, speed);

    return displayMissileInfo(missile);
}

void MissilesMenu::displayMissileInfo(Missile *missile) {
    if (!missile) return;
    printMissileInfo(missile);
    cout << endl << (*t)("delete", "missiles.info") << endl;
    return keydownHandle(ui->getPressedKey, {
            {Keys::TAB,   [this, missile]() {
                ui->toggleLocale();
                return displayMissileInfo(missile);
            }},
            {Keys::ESC,   [this]() {
                ui->setCurrentPage(Pages::MISSILES_MENU);
                return;
            }},
            {Keys::KEY_D, [this, missile]() {
                return deleteMissile(missile);
            }}
    });
}

void MissilesMenu::printMissileInfo(Missile *missile) {
    clearScreen();
    printKeybinds();
    cout << endl;
    cout << (*t)("id", "missiles.info") << ": " << missile->getId() << endl;
    cout << (*t)("name", "missiles.info") << ": " << missile->getName() << endl;
    cout << (*t)("calibre", "missiles.info") << ": " << missile->getCalibre() << " " << (*t)("mm", "measurement-units")
         << endl;
    cout << (*t)("length", "missiles.info") << ": " << missile->getLength() << " " << (*t)("m", "measurement-units")
         << endl;
    cout << (*t)("weight", "missiles.info") << ": " << missile->getWeight() << " " << (*t)("kg", "measurement-units")
         << endl;
    cout << (*t)("flight-range", "missiles.info") << ": " << missile->getFlightRange() << " "
         << (*t)("km", "measurement-units") << endl;
    cout << (*t)("impact-area", "missiles.info") << ": " << missile->getImpactArea() << " "
         << (*t)("m", "measurement-units") << endl;
    cout << (*t)("speed", "missiles.info") << ": " << missile->getSpeed() << " "
         << (*t)("m/s", "measurement-units") << endl;
}

Missile *MissilesMenu::findMissile() {
    cout << endl;
    string missileId = vi::inputString((*t)("enter-missile-id", "missiles.general"));
    try {
        return service->getById(missileId);
    } catch (EntityNotFound &e) {
        cout << (*t)("missile-doesnt-exist", "missiles.general") << endl;
        cout << (*t)("continue", "general");
        _getch();
        ui->setCurrentPage(Pages::MISSILES_MENU);
        return nullptr;
    }
}

void MissilesMenu::deleteMissile(Missile *missile) {
    if (!missile) return;
    string missileId = missile->getId();
    service->deleteOne(missileId);
    cout << (*t)("successfully-deleted", "missiles.delete", {{"missile-id", missileId}});
    cout << (*t)("continue", "general");
    _getch();
    ui->setCurrentPage(Pages::MISSILES_MENU);
}

void MissilesMenu::displayMissilesList() {
    vector<Missile *> missiles = service->getAll();
    printMissilesList(missiles);
    cout << endl << (*t)("get-info", "missiles.list") << endl;
    return keydownHandle(ui->getPressedKey, {
            {Keys::TAB,   [this]() {
                ui->toggleLocale();
                return displayMissilesList();
            }},
            {Keys::ESC,   [this]() {
                ui->setCurrentPage(Pages::MISSILES_MENU);
                return;
            }},
            {Keys::KEY_I, [this]() {
                return findAndDisplayMissileInfo();
            }}
    });
}

void MissilesMenu::findAndDisplayMissileInfo() {
    Missile *missile = findMissile();
    return displayMissileInfo(missile);
}

void MissilesMenu::printMissilesList(vector<Missile *> list) {
    clearScreen();
    printKeybinds();
    cout << (*t)("title", "missiles.list") << endl;
    if (list.empty()) {
        cout << (*t)("empty-list", "general") << endl;
        return;
    }
    for (auto const &missile: list) {
        cout << (*t)("id", "missiles.info") << ": " << missile->getId() << endl;
        cout << (*t)("name", "missiles.info") << ": " << missile->getName() << endl;
        cout << (*t)("calibre", "missiles.info") << ": " << missile->getCalibre() << " "
             << (*t)("mm", "measurement-units") << endl;
    }
}
